package com.zmj.framework.util;

import cn.hutool.core.util.StrUtil;
import com.zmj.framework.base.vo.TreeNode;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author cloudplatform
 */
public class TreeUtil {
  /**
   * 两层循环实现建树
   * 
   * @param treeNodes 传入的树节点列表
   * @return
   */
  public static <T extends TreeNode> List<T> bulid(List<T> treeNodes, Object root) {

    List<T> trees = new ArrayList<T>();

    for (T treeNode : treeNodes) {

      if (root.equals(treeNode.getParentId())) {
        trees.add(treeNode);
      }

      for (T it : treeNodes) {
        if (StrUtil.equals(it.getParentId(),treeNode.getId())) {
          if (treeNode.getChildren() == null) {
            treeNode.setChildren(new ArrayList());
          }
          treeNode.add(it);
        }
      }
    }
    return trees;
  }

  /**
   * 使用递归方法建树
   * 
   * @param treeNodes
   * @return
   */
  public static <T extends TreeNode> List<T> buildByRecursive(List<T> treeNodes,Object root) {
    List<T> trees = new ArrayList<T>();
    for (T treeNode : treeNodes) {
      if (root.equals(treeNode.getParentId())) {
        trees.add(findChildren(treeNode, treeNodes));
      }
    }
    return trees;
  }

  /**
   * 递归查找子节点
   * 
   * @param treeNodes
   * @return
   */
  public static <T extends TreeNode> T findChildren(T treeNode, List<T> treeNodes) {
    for (T it : treeNodes) {
      if (StrUtil.equals(treeNode.getId() ,it.getParentId())) {
        if (treeNode.getChildren() == null) {
          treeNode.setChildren(new ArrayList());
        }
        treeNode.add(findChildren(it, treeNodes));
      }
    }
    return treeNode;
  }

  public static <T extends TreeNode> List<T> buildTree(List<T> treeNodes, String root) {
    Map<String, List<T>> sub = treeNodes.stream()
            .filter(node -> !root.equals(node.getParentId()))
            .collect(Collectors.groupingBy(node -> node.getParentId()));

    treeNodes.forEach(node -> {
      node.setChildren(sub.get(node.getId()));
    });
    List<T> treeData = treeNodes.stream().filter(node -> root.equals(node.getParentId())).collect(Collectors.toList());
    return treeData;
  }

}
